#include "ServiceGetDataSetDirectory.h"

CServiceGetDataSetDirectory::CServiceGetDataSetDirectory(void)
{
    ServiceName();
}

CServiceGetDataSetDirectory::~CServiceGetDataSetDirectory(void)
{
    if (m_datasetItem!=NULL)
    {
        delete m_datasetItem;
        m_datasetItem=NULL;
    }
}
BOOL CServiceGetDataSetDirectory::OnGetDataSetDirectory(const char * szDataSetRef, CMTree & tree)
{
    PrintTree(tree);
}
void CServiceGetDataSetDirectory::ServiceName()
{
    printf("Service:GetDataSetDirectory\n");
}
void CServiceGetDataSetDirectory::SetDataSetItem(QTreeWidgetItem *treeItem)
{
    m_datasetItem=treeItem;
}
void CServiceGetDataSetDirectory::PrintTree(CMTree & tree)
{
    int i, level;
    int up;
    BOOL ret;
    CAcsiVar var;

    ret = tree.GotoRoot();
    i = 0;
    level = 1;
    up = 0;

    while(ret == TRUE)
    {
        printf("    ");

        for(i = 0; i < level - 1; i++)
        {
            printf("  ");
        }

        if(up != 0)
        {
            printf("}");
            printf("\n");

            ret = tree.GotoNext();

            if(ret == TRUE)
            {
                up = 0;
            }
            else
            {
                ret = tree.GotoParent();
                level--;
            }
        }
        else if(!tree.IsLeaf())
        {
            if(tree.pNode->len > 0)
            {
                var = (AcsiVariant *)tree.pNode->data;
                PrintVar(var);
            }

            level++;
            printf("{");
            printf("\n");
            ret = tree.GotoChild();
        }
        else
        {
            var = (AcsiVariant *)tree.pNode->data;
            PrintVar(var);
            printf("\n");
            ret = tree.GotoNext();

            if(!ret)
            {
                up = 1;
                ret = tree.GotoParent();
                level--;
            }
        }
    }
}

void CServiceGetDataSetDirectory::PrintType(int type, int size)
{
    printf("  (");

    switch(type)
    {
    case BOOL_CODE:
        printf("bool");
        break;
    case BITS_CODE:
        printf("bstr%d", size);
        break;
    case INT_CODE:
        if(size == 1)
        {
            printf("char");
        }
        else if(size == 2)
        {
            printf("short");
        }
        else if(size == 4)
        {
            printf("int");
        }
        else
        {
            printf("int%d", size);
        }
        break;
    case UINT_CODE:
        if(size == 1)
        {
            printf("byte");
        }
        else if(size == 2)
        {
            printf("word");
        }
        else if(size == 4)
        {
            printf("uint");
        }
        else
        {
            printf("uint%d", size);
        }
        break;
    case FLOAT_CODE:
        if(size == 5)
        {
            printf("float");
        }
        else if(size == 9)
        {
            printf("double");
        }
        else
        {
            printf("float%d", size);
        }
        break;
    case OCT_CODE:
        printf("oct%d", size);
        break;
    case VSTR_CODE:
        printf("vstr%d", size);
        break;
    case BTIME_CODE:
        printf("btime%d", size);
        break;
    case UTF8_STR_CODE:
        printf("utf8str%d", size);
        break;
    case UTCTIME_CODE:
        printf("utc");
        break;
    default:
        printf("%d, %d", type, size);
        break;
    }

    printf(")", size);
}

void CServiceGetDataSetDirectory::PrintVar(CAcsiVar & var)
{
    int i;
    struct tm gm;
    char * name;
    unsigned char * data;
    TimeStamp * time;

    name = var.GetName();

    if(name != NULL)
    {
        printf(name);
        QTreeWidgetItem *childitem=new QTreeWidgetItem(QStringList()<<QLatin1String(name));
        m_datasetItem->addChild(childitem);
        if(var.GetMmsType() >= 0)
        {
            PrintType(var.GetMmsType(), var.GetMmsSize());
        }

        return;
    }

    //  if(var.GetVarSize() > 0){
    switch(var.GetVarType())
    {
    case BDT_BOOLEAN:
        if(var.GetBool() == 0)
        {
            printf("Bool:  F");
        }
        else
        {
            printf("Bool:  T");
        }
        break;
    case BDT_INT8:
    case BDT_INT16:
    case BDT_INT32:
        printf("int:  %d", (int)var);
        break;
    case BDT_INT8U:
    case BDT_INT16U:
    case BDT_INT32U:
        printf("uint:  %d", (unsigned int)var);
        break;
    case BDT_FLOAT32:
    case BDT_FLOAT64:
        printf("float:  %f", (double)var);
        break;
    case BDT_OCTETSTRING:
        printf("oct:  ");
        data = var.GetOctStr();

        for(i = 0; i < var.GetOctLen(); i++)
        {
            printf("%02x ", data[i]);
        }

        break;
    case BDT_VISIBLESTRING:
        printf("str:  %s", (char *)var);
        break;
    case BDT_UNICODESTRING:
        {
            char str[256];
            strcpy(str, "");
#ifdef WIN32
            WCHAR wstr[512];
            wstr[0] = 0;
            MultiByteToWideChar(CP_UTF8, 0, (char *)(var.GetUtf8Str()), -1, wstr,
                sizeof(wstr));
            WideCharToMultiByte(CP_ACP, 0, wstr, -1, str, sizeof(str), NULL, NULL);
#endif
            printf("utf8str:  %s", str);
        }
        break;
    case BDT_BITSTRING:
        printf("bits:  ");
        data = var.GetBitStr();

        for(i = 0; i < var.GetBitLen(); i++)
        {
            if((data[i / 8] & (1 << (7 - i % 8))) == 0)
            {
                printf("0");
            }
            else
            {
                printf("1");
            }
        }

        break;
    case BDT_TimeStamp:
        //          var.GetTime().secs -= 28800 * 2;
        time = &var.GetTime();
        gm = * localtime(&time->secs);
        printf("time:  %04d-%02d-%02d %02d:%02d:%02d %03d  %x",
            gm.tm_year + 1900, gm.tm_mon + 1, gm.tm_mday, gm.tm_hour, gm.tm_min, gm.tm_sec,
            GetTimeStampMsec(time), time->qflags);
        //              (int)((1000.0 * var.GetTime().fraction) / 0x00ffffff), var.GetTime().qflags);
        break;
    default:
        PrintType(var.GetMmsType(), var.GetMmsSize());
        break;
    }
    //  }
}

